package com.mecuros.support.pipeline;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.mecuros.common.enums.RespStatusEnum;
import com.mecuros.common.vo.BasicResultVO;
import com.mecuros.support.exception.ProcessException;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;

/**
 * @Classname ProcessController
 * @Description 流程控制器
 * @Date 2022/5/14 5:39 下午
 * @Created by yujianbo
 */
@Slf4j
@Data
public class ProcessController {

    /**
     * 模板映射
     */
    private Map<String,ProcessTemplate> templateConfig = null;

    /**
     * 执行责任链
     * @param context
     * @return 返回上下文内容
     */
    public ProcessContext process(ProcessContext context){
        /**
         * 前置检查
         */
        try {
            preCheck(context);
        } catch (ProcessException e) {
            e.printStackTrace();
        }

        // 遍历流程节点
        List<BusinessProcess> processList = templateConfig.get(context.getCode()).getProcessList();
        for (BusinessProcess businessProcess:processList){
            businessProcess.process(context);
            if (context.getNeedBreak()){
                break;
            }
        }

        return context;
    }

    /**
     * 参数前置检查
     * @param context 执行上下文
     */
    private void preCheck(ProcessContext context) throws ProcessException{
        // 上下文
        if (context == null){
            context = new ProcessContext();
            context.setResponse(BasicResultVO.fail(RespStatusEnum.CONTEXT_IS_NULL));
            throw new ProcessException(context);
        }

        // 业务代码
        String businessCode = context.getCode();
        if (StrUtil.isNotBlank(businessCode)){
            context.setResponse(BasicResultVO.fail(RespStatusEnum.BUSINESS_CODE_IS_NULL));
            throw new ProcessException(context);
        }

        // 执行模板
        ProcessTemplate processTemplate = templateConfig.get(businessCode);
        if (processTemplate == null){
            context.setResponse(BasicResultVO.fail(RespStatusEnum.PROCESS_TEMPLATE_IS_NULL));
            throw new ProcessException(context);
        }

        // 执行模板列表
        List<BusinessProcess> processList = processTemplate.getProcessList();
        if (CollUtil.isEmpty(processList)){
            context.setResponse(BasicResultVO.fail(RespStatusEnum.PROCESS_LIST_IS_NULL));
            throw new ProcessException(context);
        }
    }
}
